<template>
  <div class="upload-v1">
    <!-- 表单 -->
    <el-form :model="form">
      <!-- 下拉框 -->
      <el-form-item label="创建类型：" :label-width="formLabelWidth">
        <div class="block">
          <el-select v-model="type" placeholder="请选择">
            <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
            </el-option>
          </el-select>
        </div>
      </el-form-item>
      <!-- 文件夹选择 -->
      <el-form-item label="文件夹：" :label-width="formLabelWidth">
        <div class="block">
          <el-cascader v-model="form.folderId" :options="folders" :props="{checkStrictly: true }"
            clearable></el-cascader>
        </div>
      </el-form-item>
      <!-- 文件上传 -->
      <el-form-item v-if="type=='file'" label="上传方式：" :label-width="formLabelWidth">
        <el-switch style="display: block;margin-top: 10px;" v-model="encrypt" active-color="#ff4949"
          inactive-color="#13ce66" active-text="加密上传" inactive-text="普通上传">
        </el-switch>
      </el-form-item>

      <el-form-item v-if="type=='file'" label="文件：" :label-width="formLabelWidth">

        <el-upload style="width: 250px;" :limit="1" class="upload-demo" ref="upload" action="" :file-list="fileList"
          :auto-upload="false" :on-remove="handleRemove">
          <el-button slot="trigger" size="small" type="primary">选取文件</el-button>

          <el-button v-if="!isTrue" :disabled="isTrue" style="margin-left: 10px" size="small" type="success"
            @click="submitUpload">上传到服务器</el-button>

          <el-button v-else style="margin-left: 10px" size="small" type="danger" @click="isTrue = false">暂停</el-button>
        </el-upload>
        <!-- 进度条 -->
        <el-progress style="margin-top: 10px;" class="progress" :text-inside="true" :stroke-width="24"
          :percentage="uploadPercentage" status="success">
        </el-progress>

        <p>使用加密上传会损耗计算机性能，上传速度会减慢，您可以自行在本地加密后再进行上传</p>

      </el-form-item>

      <template v-if="type == 'folder'">

        <el-form-item label="文件夹名：" :label-width="formLabelWidth">
          <el-input v-model="folderName" placeholder="请输入内容" style="width: 300px;"></el-input>
        </el-form-item>

        <el-form-item label="" :label-width="formLabelWidth">
          <el-button type="primary" @click="creatFolder">创建</el-button>
        </el-form-item>

      </template>

      <template v-if="type == 'share'">

        <el-form-item v-if="!forever" label="共享日期：" :label-width="formLabelWidth">
          <el-date-picker v-model="date" type="daterange" align="right" unlink-panels range-separator="至"
            start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="pickerOptions">
          </el-date-picker>
        </el-form-item>

        <el-form-item label="是否永久：" :label-width="formLabelWidth">
          <el-switch v-model="forever" active-color="#13ce66" inactive-color="#ff4949">
          </el-switch>
        </el-form-item>

        <el-form-item label="提取密码：" :label-width="formLabelWidth">
          <el-input v-model="password" placeholder="请输文件提取密码" style="width: 300px;"></el-input>
        </el-form-item>

        <el-form-item label="" :label-width="formLabelWidth">
          <el-button type="primary" @click="creatShare">创建</el-button>
        </el-form-item>
      </template>

    </el-form>

  </div>
</template>

<script>
  import apiUrl from '@/api/url'
  import link from '@/api/Link'
  import BlobToBase64 from '@/util/FileToBase64'
  import fileMd5 from '@/util/FileMD5'
  import router from "@/router";
  import CryptoJS from 'crypto-js'
  export default {
    name: 'create',
    data () {
      return {
        //提取密码
        password: '',
        //是否永久
        forever: false,
        //共享时间
        date: null,
        //快捷时间
        pickerOptions: {
          shortcuts: [{
            text: '最近一周',
            onClick (picker) {
              const start = new Date();
              const end = new Date();
              end.setTime(end.getTime() + 3600 * 1000 * 24 * 7);
              picker.$emit('pick', [start, end]);
            }
          }, {
            text: '最近一个月',
            onClick (picker) {
              const end = new Date();
              const start = new Date();
              end.setTime(end.getTime() + 3600 * 1000 * 24 * 30);
              picker.$emit('pick', [start, end]);
            }
          }, {
            text: '最近三个月',
            onClick (picker) {
              const end = new Date();
              const start = new Date();
              end.setTime(end.getTime() + 3600 * 1000 * 24 * 90);
              picker.$emit('pick', [start, end]);
            }
          }]
        },

        form: {
          folderId: [],
        },
        //上传进度
        uploadPercentage: 0, // 上传进度条的进度值0-100 默认为0% 可以自定义进度条样
        isTrue: false,

        path: '',
        shardIndex: 1,
        fileList: [],
        formLabelWidth: '120px',
        folders: [],
        //创建类型
        options: [{
          value: 'folder',
          label: '文件夹创建'
        }, {
          value: 'file',
          label: '文件上传'
        }, {
          value: 'share',
          label: '文件共享'
        }],
        type: 'file',
        //创建文件夹--文件夹名
        folderName: '',
        //是否加密
        encrypt: false,
        //文件唯一标识
        openKey: '',
      }

    },
    methods: {
      //初始化
      init () {

        let user = JSON.parse(localStorage.getItem('user'))
        let data = {
          state: 0,
          id: user.rootId
        }
        //下拉框--获取数据
        link(apiUrl.baseUrl + '/sys/folder/findList/v2', 'POST', JSON.stringify(data), null).then((ok) => {
          this.folders = []
          this.folders.push(this.cascaderInit(ok.data.data))
        })

      },
      //构建下拉框数据
      cascaderInit (data) {
        if (!data) {
          return
        }
        let folders = {
          value: data.folder.id,
          label: data.folder.folderName,
          children: []
        }

        data.childFolders.forEach(element => {
          folders.children.push(this.cascaderInit(element))
        });

        return folders;
      },

      //上传文件
      async submitUpload () {
        if (this.form.folderId.length === 0) {
          this.$message.error('请选择文件夹')
          return
        }
        if (this.$refs.upload._data.uploadFiles[0] == null) {
          this.$message.error('请选择文件')
          return
        }
        let file = this.$refs.upload._data.uploadFiles[0].raw
        const { name, size, type } = file
        this.$message({
          message: "开始上传",
          type: "success",
        });
        //文件预检查
        if (this.openKey == '') {
          this.openKey = await fileMd5(file, 2 * 1024 * 1024)
        }
        let preCheckData = {
          fileName: name,
          folderId: this.form.folderId[this.form.folderId.length - 1],
          openKey: this.openKey,
          size: size
        }
        await link(apiUrl.baseUrl + '/sys/file/preCheck/v1', 'POST', JSON.stringify(preCheckData)).then((ok) => {
          if (ok.data.code === 0) {
            if (ok.data.data.exist === true) {
              this.uploadPercentage = 100;
              this.$refs.upload.clearFiles()
              this.$message({
                message: "上传成功",
                type: "success",
              });
              this.isTrue = false
              this.openKey = ''
            } else {
              this.shardIndex = ok.data.data.index + 1
              this.path = ok.data.data.path
              this.isTrue = true
            }
          } else {
            this.$message.error(ok.data.msg)
            this.isTrue = false
          }
        })

        //文件分片上传
        let chunkSize = 2 * 1024 * 1024
        let shardIndex = this.shardIndex;
        let start = (shardIndex - 1) * chunkSize
        let total = Math.ceil(size / chunkSize)
        let blob = null;
        const key = CryptoJS.enc.Utf8.parse('qwertyuiopoiuytr'); //十六位十六进制数作为密钥
        const iv = CryptoJS.enc.Utf8.parse('poiuytrewqwertyu');
        while (start < size && this.isTrue) {
          //分片请求数据
          let data = {
            name: name,
            folderId: this.form.folderId[this.form.folderId.length - 1],
            openKey: this.openKey,
            suffix: name.substring(name.lastIndexOf('.')),
            size: size,
            shardIndex: shardIndex,
            shardSize: 0,
            shardTotal: total,
            shard: "",
            path: this.path,
            encrypt: this.encrypt ? '1' : '0'
          };
          if (start + chunkSize > size) {
            blob = file.slice(start, size);
            start = size;
          } else {
            blob = file.slice(start, start + chunkSize);
            start += chunkSize;
          }
          //Base64编码加密
          let Base64 = await BlobToBase64(blob)
          //文件加密
          if (this.encrypt) {
            let encryptResult = await CryptoJS.AES.encrypt(Base64, key, { iv: iv, })
            data.shard = encryptResult.toString()
          } else {
            data.shard = Base64
          }
          data.shardSize = blob.size;
          shardIndex++;
          await link(apiUrl.baseUrl + '/sys/file/upload/v1', 'POST', JSON.stringify(data), null).then((ok) => {
            if (ok.data.code == 0) {
              this.uploadPercentage = Math.ceil((start / size) * 100);
            } else {
              //分片上传失败
              this.$message.error(ok.data.msg)
              this.isTrue = false
            }
          })

          if (this.isTrue && this.uploadPercentage == 100) {

            this.$refs.upload.clearFiles()
            this.$message({
              message: "上传成功",
              type: "success",
            });
            this.uploadPercentage = 0
            this.isTrue = false
            this.openKey = ''
            return
          }
          data = null;
        }

      },

      //创建文件夹
      creatFolder () {
        if (this.form.folderId.length === 0) {
          this.$message.error('请选择文件夹')
          return
        }
        if (this.folderName == '') {
          this.$message.error('文件夹名不能为空')
          return
        }

        let data = {
          folderName: this.folderName,
          pid: this.form.folderId[this.form.folderId.length - 1],
        }

        link(apiUrl.baseUrl + '/sys/folder/createFolder/v1', 'POST', JSON.stringify(data)).then(ok => {
          if (ok.data.code == 0) {
            this.$message({
              message: "创建成功",
              type: "success",
            });
            this.init()
          } else {
            this.$message.error(ok.data.msg)
          }
        })


      },

      //创建共享文件夹
      creatShare () {

        if (this.form.folderId.length === 0) {
          this.$message.error('请选择文件夹')
          return
        }
        if (this.date.length == 0 && !this.forever) {
          this.$message.error('请选择共享时间')
          return
        }
        if (this.password == '') {
          this.$message.error('提取密码不能为空')
          return
        }
        if (this.password.length != 4) {
          this.$message.error('提取密码为4位')
          return
        }


        let data = {
          folderId: this.form.folderId[this.form.folderId.length - 1],
          startDate: this.date[0],
          deadlineDate: this.date[1],
          password: this.password,
          forever: this.forever == true ? 1 : 0
        }

        link(apiUrl.baseUrl + '/sys/share/createShare/v1', 'POST', JSON.stringify(data)).then(ok => {
          if (ok.data.code == 0) {
            this.$message({
              message: "创建成功",
              type: "success",
            });
            router.push("/shareFolder");
          } else {
            this.$message.error(ok.data.msg)
          }
        })

      },
      //文件取消监听器
      handleRemove (file, fileList) {
        this.openKey = ''
      },
    },
    mounted () {
      this.type = this.$route.query.type ? this.$route.query.type : 'file'
      this.init()
    },
    watch: {

    }
  };
</script>

<style scoped>
  .progress {
    width: 300px;
  }

  .upload-v1 {
    margin-top: 20px;
  }
</style>